package com.egg.basic.service.pay.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.egg.basic.entity.pay.PayRecord;
import com.egg.basic.enums.pay.ClientTypeEnum;
import com.egg.basic.enums.pay.PayTypeEnum;
import com.egg.basic.enums.pay.TradeStateEnum;
import com.egg.basic.mapper.pay.PayRecordMapper;
import com.egg.basic.service.pay.factory.IPayFactory;
import com.egg.basic.service.pay.IPayRecordService;
import com.egg.common.core.constant.CoreConstant;
import com.egg.common.core.exception.CustomException;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.mybatis.service.impl.BaseServiceImpl;
import com.egg.common.util.IdGenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Optional;

/**
 * <p>
 * 支付记录 服务实现类
 * </p>
 *
 * @author east
 * @since 2021-11-26
 */
@Slf4j
@Service
public class PayRecordServiceImpl extends BaseServiceImpl<PayRecordMapper, PayRecord> implements IPayRecordService {


    @Override
    public Optional<PayRecord> findSuccess(String businessType, Serializable businessId) {
        if (ObjectUtil.isEmpty(businessType) || ObjectUtil.isEmpty(businessId)) {
            return Optional.empty();
        }
        LambdaQueryWrapper<PayRecord> qw = buildLambdaSortQw();
        qw.eq(PayRecord::getBusinessType, businessType)
                .eq(PayRecord::getBusinessId, businessId)
                .eq(PayRecord::getTradeState, TradeStateEnum.SUCCESS.getCode());
        qw.last("LIMIT 1");
        return Optional.ofNullable(getOne(qw));
    }

    @Override
    public Optional<PayRecord> findWait(String businessType, Serializable businessId) {
        if (ObjectUtil.isEmpty(businessType) || ObjectUtil.isEmpty(businessId)) {
            return Optional.empty();
        }
        LambdaQueryWrapper<PayRecord> qw = buildLambdaSortQw();
        qw.eq(PayRecord::getBusinessType, businessType)
                .eq(PayRecord::getBusinessId, businessId)
                .eq(PayRecord::getTradeState, TradeStateEnum.WAIT.getCode());
        qw.last("LIMIT 1");
        return Optional.ofNullable(getOne(qw));
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public String add(PayTypeEnum payType, ClientTypeEnum clientType, String businessType, String businessId, Optional<Long> uerId, Long amount, String subject) {
        IPayFactory payFactory = IPayFactory.findFactory(payType);
        if (null == payFactory) {
            throw new CustomException(String.format("[%s]端异常", payType.getMessage()));
        }
        PayRecord pr = new PayRecord();
        pr.setId(IdGenUtil.longId());
        pr.setUserId(uerId.orElse(CoreConstant.DEFAULT_ID));
        pr.setBusinessType(businessType);
        pr.setBusinessId(businessId);
        pr.setAmount(amount);
        pr.setPayType(payType.getCode());
        pr.setSubject(subject);
        pr.setClientType(clientType.getCode());
        pr.setTradeState(TradeStateEnum.WAIT.getCode());
        ResponseData<String> ret = payFactory.add(pr);
        if (!ret.isSuccess()) {
            throw new CustomException(ret.getMsg());
        }
        baseSave(pr);
        return ret.getData();
    }


}
